// ignore_for_file: non_constant_identifier_names

part of YFree;

int lastClickTime = 0;

///按钮
Widget YButton({required Widget child, double? width, double? height, Color? color, Decoration? decoration, EdgeInsetsGeometry? padding, EdgeInsetsGeometry? margin, required Function() onTap, bool enable = true, bool isInk = false, int? tapTime, BorderRadius? borderRadius = BorderRadius.zero}) {
  return Container(
    width: width,
    height: height,
    margin: margin,
    child: ClipRRect(
      borderRadius: borderRadius,
      child: Container(
        color: decoration == null ? color : null,
        decoration: decoration,
        child: isInk
            ? YInkButton(
                Padding(padding: padding ?? EdgeInsets.zero, child: child),
                onTap: onTap,
                enable: enable,
                tapTime: tapTime,
              )
            : YFlatButton(
                Padding(padding: padding ?? EdgeInsets.zero, child: child),
                onClick: onTap,
                enable: enable,
                tapTime: tapTime,
              ),
      ),
    ),
  );
}

@Deprecated("Use YButton instead")
TextButton YFlatButton(Widget? widget, {required Function() onClick, bool enable = true, int? tapTime}) {
  return TextButton(
    onPressed: enable ? () => _doTap(onClick, tapTime: tapTime) : () {},
    style: ButtonStyle(
      padding: MaterialStateProperty.all(EdgeInsets.zero),
      foregroundColor: MaterialStateProperty.all(Colors.black),
      backgroundColor: MaterialStateProperty.all(Colors.transparent),
      overlayColor: MaterialStateProperty.all(enable ? Colors.black.withOpacity(0.1) : Colors.transparent),
      textStyle: MaterialStateProperty.all(const TextStyle(fontSize: 14)),
    ),
    child: widget ?? YEmpty(),
  );
}

Material YInkButton(Widget? widget, {color = Colors.transparent, bool enable = true, int? tapTime, required GestureTapCallback onTap}) {
  return Material(color: color, child: InkWell(onTap: enable ? () => _doTap(onTap, tapTime: tapTime) : () {}, child: widget ?? YEmpty()));
}

Widget YInkRoundButton(Widget? widget, {color = Colors.transparent, bool enable = true, int? tapTime, required GestureTapCallback onTap, double size = 70.0}) {
  return SizedBox(width: size, height: size, child: ClipOval(child: Material(color: color, child: InkResponse(radius: size, onTap: enable ? () => _doTap(onTap, tapTime: tapTime) : () {}, child: widget ?? YEmpty()))));
}

void _doTap(Function() onClick, {int? tapTime}) {
  var nowTime = DateTime.now().millisecondsSinceEpoch;
  if ((nowTime - lastClickTime) > (tapTime ?? 100)) {
    onClick();
    lastClickTime = nowTime;
  }
}

///居右组件
Widget YRight({required Widget child}) => Row(children: [YExpanded(), child]);

///空组件
Widget YEmpty() => YEmptyContainer();

@Deprecated("Use YEmpty instead")
Widget YEmptyContainer() => const SizedBox(width: 0, height: 0);

///占位组件
Widget YExpanded({int flex = 1}) => Expanded(flex: flex, child: YEmpty());

///间距组件
Widget YSpacer({double width = 0, double height = 0}) => SizedBox(width: width, height: height);

///标题组件
Expanded YTitleWidget(String? title, {Color? navBarTitleColor}) => Expanded(child: Center(child: Text(title ?? "", style: TextStyle(color: navBarTitleColor ?? YConfig.navBarTitleColor, fontSize: 18, fontWeight: FontWeight.w700))));

///导航条组件
Stack YAppBarWidget({String? title, Widget? leftWidget, Function()? onLeftClick, Widget? rightWidget, Function()? onRightClick, Widget? leftContainer, Widget? rightContainer, Widget? centerContainer}) {
  return Stack(children: <Widget>[
    Row(children: <Widget>[
      leftContainer ?? SizedBox(width: yNavBarHeight(), height: yNavBarHeight(), child: YFlatButton(leftWidget, onClick: () => onLeftClick!())),
      Expanded(child: Container()),
      rightContainer ?? SizedBox(width: yNavBarHeight(), height: yNavBarHeight(), child: YFlatButton(rightWidget, onClick: () => onRightClick!())),
    ]),
    Row(children: <Widget>[centerContainer == null ? YTitleWidget(title) : Expanded(child: Center(child: centerContainer))]),
  ]);
}

///加载图像
Widget YImage(double? width, double? height, String url, {BoxFit fit = BoxFit.contain, String? imagePlaceHolder}) {
  if (yIsNullOrEmpty(url)) return Image.asset(yIsNullOrEmpty(imagePlaceHolder) ? YConfig.imagePlaceHolder : imagePlaceHolder!, width: width, height: height, fit: fit);
  return ExtendedImage.network(
    url,
    loadStateChanged: (ExtendedImageState state) {
      switch (state.extendedImageLoadState) {
        case LoadState.loading:
          return Image.asset(yIsNullOrEmpty(imagePlaceHolder) ? YConfig.imagePlaceHolder : imagePlaceHolder!, width: width, height: height, fit: fit);
        case LoadState.completed:
          return state.completedWidget;
        case LoadState.failed:
          return yIsNullOrEmpty(imagePlaceHolder) ? SizedBox(width: width, height: height, child: const Icon(Icons.error)) : Image.asset(imagePlaceHolder!, width: width, height: height, fit: fit);
      }
    },
    width: width,
    height: height,
    fit: fit,
  );
}

///加载图像(圆角)
Widget YImageCorner(double? width, double? height, String url, double corner, {BoxFit fit = BoxFit.cover, String? imagePlaceHolder}) {
  return ClipRRect(borderRadius: BorderRadius.all(Radius.circular(corner)), child: YImage(width, height, url, fit: fit, imagePlaceHolder: imagePlaceHolder));
}

///加载图像(圆形)
Widget YImageCircle(double? width, double? height, String url, {BoxFit fit = BoxFit.cover, String? imagePlaceHolder}) {
  return ClipOval(child: YImage(width, height, url, fit: fit, imagePlaceHolder: imagePlaceHolder));
}

// final kTransparentImage = Uint8List.fromList([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D, 0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE]);

Widget YImage2(double? width, double? height, String url, {BoxFit fit = BoxFit.contain, String? imagePlaceHolder}) {
  if (yIsNullOrEmpty(url)) return Image.asset(yIsNullOrEmpty(imagePlaceHolder) ? YConfig.imagePlaceHolder : imagePlaceHolder!, width: width, height: height, fit: fit);
  return FadeInImage.assetNetwork(placeholder: yIsNullOrEmpty(imagePlaceHolder) ? YConfig.imagePlaceHolder : imagePlaceHolder!, image: url, width: width, height: height, fit: fit);
//  return FadeInImage.memoryNetwork(placeholder: kTransparentImage, image: url, width: width, height: height, fit: fit);
}

Widget YImageCorner2(double? width, double? height, String url, double corner, {BoxFit fit = BoxFit.cover, String? imagePlaceHolder}) {
  return ClipRRect(borderRadius: BorderRadius.all(Radius.circular(corner)), child: YImage2(width, height, url, fit: fit, imagePlaceHolder: imagePlaceHolder));
}

Widget YImageCircle2(double? width, double? height, String url, {BoxFit fit = BoxFit.cover, String? imagePlaceHolder}) {
  return ClipOval(child: YImage2(width, height, url, fit: fit, imagePlaceHolder: imagePlaceHolder));
}

///下拉刷新组件
Widget YRefreshContainer({required Widget child, Function()? onRefresh, ScrollController? scrollController, Header? header, Footer? footer, Function()? onLoadMore, bottomBouncing = true, scrollbar = true}) {
  var easyRefresh = EasyRefresh(
    onRefresh: onRefresh != null ? () => onRefresh() : null,
    onLoad: onLoadMore != null ? () => onLoadMore() : null,
    bottomBouncing: bottomBouncing,
    scrollController: scrollController,
    header: header ?? (onRefresh != null ? BezierCircleHeader(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor) : null),
    footer: footer ?? (onLoadMore != null ? BallPulseFooter(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor, enableInfiniteLoad: false) : null),
    child: Container(
      constraints: const BoxConstraints(minHeight: 300),
      child: child,
    ),
  );
  return scrollbar ? Scrollbar(child: easyRefresh) : easyRefresh;
}

Widget YRefreshListView<T>({required List<T> models, Function()? onRefresh, required Function(BuildContext context, int index, T model) itemBuilder, ScrollController? scrollController, Header? header, Footer? footer, Function()? onLoadMore, bottomBouncing = true, scrollbar = true, EdgeInsets padding = EdgeInsets.zero}) {
  var easyRefresh = EasyRefresh(
    onRefresh: onRefresh != null ? () => onRefresh() : null,
    onLoad: onLoadMore != null ? () => onLoadMore() : null,
    bottomBouncing: bottomBouncing,
    scrollController: scrollController,
    header: header ?? (onRefresh != null ? BezierCircleHeader(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor) : null),
    footer: footer ?? (onLoadMore != null ? BallPulseFooter(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor, enableInfiniteLoad: false) : null),
    child: Container(
      constraints: const BoxConstraints(minHeight: 300),
      child: ListView.builder(
        padding: padding,
        primary: false,
        shrinkWrap: true,
        itemCount: models.length,
        itemBuilder: (context, index) => itemBuilder(context, index, models[index]),
      ),
    ),
  );
  return scrollbar ? Scrollbar(child: easyRefresh) : easyRefresh;
}

Widget YRefreshStaticListView({required List<Widget> children, Function()? onRefresh, ScrollController? scrollController, Header? header, Footer? footer, Function()? onLoadMore, bottomBouncing = true, scrollbar = true, EdgeInsets padding = EdgeInsets.zero}) {
  var easyRefresh = EasyRefresh(
    onRefresh: onRefresh != null ? () => onRefresh() : null,
    onLoad: onLoadMore != null ? () => onLoadMore() : null,
    bottomBouncing: bottomBouncing,
    scrollController: scrollController,
    header: header ?? (onRefresh != null ? BezierCircleHeader(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor) : null),
    footer: footer ?? (onLoadMore != null ? BallPulseFooter(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor, enableInfiniteLoad: false) : null),
    child: Container(
      constraints: const BoxConstraints(minHeight: 300),
      child: ListView(
        padding: padding,
        primary: false,
        shrinkWrap: true,
        children: children,
      ),
    ),
  );
  return scrollbar ? Scrollbar(child: easyRefresh) : easyRefresh;
}

Widget YRefreshGridView<T>({required List<T> models, required SliverGridDelegate gridDelegate, Function()? onRefresh, required Function(BuildContext context, int index, T model) itemBuilder, ScrollController? scrollController, Header? header, Footer? footer, Function()? onLoadMore, bottomBouncing = true, scrollbar = true, EdgeInsets padding = EdgeInsets.zero}) {
  var easyRefresh = EasyRefresh(
    onRefresh: onRefresh != null ? () => onRefresh() : null,
    onLoad: onLoadMore != null ? () => onLoadMore() : null,
    bottomBouncing: bottomBouncing,
    scrollController: scrollController,
    header: header ?? (onRefresh != null ? BezierCircleHeader(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor) : null),
    footer: footer ?? (onLoadMore != null ? BallPulseFooter(backgroundColor: YConfig.themeColor.withOpacity(0.1), color: YConfig.themeColor, enableInfiniteLoad: false) : null),
    child: Container(
      constraints: const BoxConstraints(minHeight: 300),
      child: GridView.builder(
        padding: padding,
        primary: false,
        shrinkWrap: true,
        gridDelegate: gridDelegate,
        itemCount: models.length,
        itemBuilder: (context, index) => itemBuilder(context, index, models[index]),
      ),
    ),
  );
  return scrollbar ? Scrollbar(child: easyRefresh) : easyRefresh;
}

///列表条目
Widget YListTile(String title, String? image, Function() onClick, {Color bgColor = Colors.transparent, double imageSize = 20, Widget? right, EdgeInsets? padding, TextStyle? titleStyle, bool enable = true}) {
  return Container(
    color: bgColor,
    child: YFlatButton(
      Container(
        padding: padding ?? const EdgeInsets.all(15),
        child: Row(
          children: <Widget>[
            image != null ? Image.asset(image, width: imageSize, height: imageSize, fit: BoxFit.fill) : YEmpty(),
            Expanded(child: Container(margin: EdgeInsets.fromLTRB(image != null ? 10 : 0, 0, 0, 0), child: Text(title, style: titleStyle ?? const TextStyle(fontSize: 15)))),
            right ?? const Offstage(offstage: true),
          ],
        ),
      ),
      onClick: onClick,
      enable: enable,
    ),
  );
}

Widget YCircularProgress({double size = 50, double strokeWidth = 4}) {
  return Center(child: SizedBox(width: size, height: size, child: CircularProgressIndicator(strokeWidth: strokeWidth)));
}

Widget YAnimatedSwitcher({required Widget child, int duration = 300}) {
  return AnimatedSwitcher(duration: Duration(milliseconds: duration), child: child);
}

GestureDetector YCIMGestureDetector(BuildContext context, Widget child) {
  return GestureDetector(child: SizedBox(width: yScreenSize().width, height: yScreenSize().height, child: child), onTap: () => yCloseInputMethod());
}

Widget YAppBar({String? title, Color? navBarTitleColor, bool canBack = true, bool divider = false, Widget? left, Widget? right, Widget? widget, String? statubar, String? navBar}) {
  var screenSize = yScreenSize();
  double statubarHeight = yStatubarHeight();
  double navBarHeight = yNavBarHeight();
  return Column(
    mainAxisSize: MainAxisSize.max,
    children: <Widget>[
      Image.asset(statubar ?? YConfig.statubar, width: screenSize.width, height: statubarHeight, fit: BoxFit.fill),
      Stack(children: <Widget>[
        Image.asset(navBar ?? YConfig.navBar, width: screenSize.width, height: navBarHeight, fit: BoxFit.fill),
        SizedBox(
          height: navBarHeight,
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.max,
            children: widget == null
                ? <Widget>[
                    SizedBox(width: navBarHeight, height: navBarHeight, child: left ?? (canBack ? YFlatButton(Icon(Icons.arrow_back_ios, color: navBarTitleColor ?? YConfig.navBarTitleColor), onClick: () => yPages.last.yFinish()) : YEmpty())),
                    YTitleWidget(title, navBarTitleColor: navBarTitleColor),
                    SizedBox(width: navBarHeight, height: navBarHeight, child: right ?? YEmpty()),
                  ]
                : <Widget>[SizedBox(width: screenSize.width, height: navBarHeight, child: widget)],
          ),
        ),
      ]),
      divider ? Divider(height: 1, color: Colors.grey.shade400) : YEmpty(),
    ],
  );
}

///侧滑菜单
class YDrawer extends StatefulWidget {
  double elevation;
  Widget? child;
  String? semanticLabel;
  double widthPercent;
  DrawerCallback? callback;
  bool? isShowing;

  YDrawer({Key? key, this.elevation = 16.0, this.child, this.semanticLabel, this.widthPercent = 0.8, this.callback}) : super(key: key);

  @override
  _YDrawerState createState() => _YDrawerState();
}

class _YDrawerState extends State<YDrawer> {
  @override
  void initState() {
    widget.isShowing = true;
    if (widget.callback != null) widget.callback!(true);
    super.initState();
  }

  @override
  void dispose() {
    widget.isShowing = false;
    if (widget.callback != null) widget.callback!(false);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Semantics(
      scopesRoute: true,
      namesRoute: true,
      explicitChildNodes: true,
      label: widget.semanticLabel ?? MaterialLocalizations.of(context).drawerLabel,
      child: ConstrainedBox(
        constraints: BoxConstraints.expand(width: MediaQuery.of(context).size.width * widget.widthPercent),
        child: Material(elevation: widget.elevation, child: widget.child),
      ),
    );
  }
}
/*
  MyWidget(context, title: testValue).yWidget, onClick: () => setState(() => testValue = "new test");

  var testValue = "test";

  class MyWidget extends YWidget {
    MyWidget(
      BuildContext context, {
      this.title,
    }) : super(context);

    String? title;

    @override
    Widget yBuild(BuildContext context) {
      yToast(yScreenSize(context).width.toString());
      return Text(title ?? "");
    }
  }
*/

abstract class YWidget extends YPage {
  YWidget(this.context);

  @override
  late BuildContext context;

  Widget get yWidget => _YBaseWidget(child: yBuild(context));

  @override
  void yOnCreate() {}

  @override
  Widget build(BuildContext context) => YEmpty();
}

class _YBaseWidget extends StatefulWidget {
  const _YBaseWidget({
    Key? key,
    required this.child,
  }) : super(key: key);

  final Widget child;

  @override
  _YBaseWidgetState createState() => _YBaseWidgetState();
}

class _YBaseWidgetState extends State<_YBaseWidget> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

class YStatefulWidget extends StatefulWidget {
  YPage Function() onCreateState;

  YStatefulWidget(this.onCreateState);

  @override
  State<StatefulWidget> createState() => onCreateState();
}
